#include "StdAfx.h"
#include "Utility.h"
#include "CustomEdit.h"

#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

IMPLEMENT_DYNAMIC(CCustomEdit, CEdit)

CCustomEdit::CCustomEdit(void)
{
	m_strText=_T("");
	m_nFontSize = 8;
	m_nFontStyle = FontStyleRegular;
	m_enFontUnit = UnitPoint;

	m_strTextFormat = NULL;
	m_pFontFamily = NULL;
	m_pFontBrush = NULL;
	m_pFont = NULL;

	m_nLineInRect = m_nLineALL = m_nMovedLine = 0;
	m_hBgDC = m_hDrawDC = m_hEditDC = NULL;
}

CCustomEdit::~CCustomEdit(void)
{
	if(m_pFont != NULL){ delete m_pFont;  m_pFont = NULL; }
	if(m_pFontBrush != NULL){ delete m_pFontBrush;  m_pFontBrush = NULL; }
	if(m_pFontFamily != NULL){ delete m_pFontFamily;  m_pFontFamily = NULL; }
	if(m_strTextFormat != NULL){ delete m_strTextFormat;  m_strTextFormat = NULL; }	
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
//Common Setting
/*********************************************************************************************************************/
/*********************************************************************************************************************/
void CCustomEdit::Initialize(HWND hPParentWnd, HWND hParentWnd, HDC hBgDC, HDC hDrawDC, int nParentx, int nParenty)
{
	m_hPParentWnd = hPParentWnd;
	m_hParentWnd = hParentWnd;

	m_hBgDC = hBgDC;
	m_hDrawDC = hDrawDC;

	::GetWindowRect(m_hPParentWnd, m_rtPPRect);
	::GetWindowRect(m_hParentWnd, m_rtPRect);

	GetWindowRect(&m_rtRect);
	m_rtRect.OffsetRect(+nParentx, +nParenty);
	m_rtRect.OffsetRect(-m_rtPRect.left, -m_rtPRect.top);

	HDC hDC = ::GetDC( m_hWnd );
	m_hEditDC = ::CreateCompatibleDC(hDC);
	HBITMAP hEditBmp = ::CreateCompatibleBitmap(hDC, m_rtRect.Width(), m_rtRect.Height());
	HBITMAP hOldBmp = (HBITMAP)::SelectObject(m_hEditDC, hEditBmp);

	GetWindowTextW(m_strText);
	if(m_strText)
	{
		CreateFont();	
		Graphics graphics(m_hEditDC);

		RectF boundingBox; int nchar;
		graphics.MeasureString(m_strText, -1, m_pFont, RectF((Gdiplus::REAL)0,    (Gdiplus::REAL)0,
			                                                 (Gdiplus::REAL)m_rtRect.Width(), (Gdiplus::REAL)m_rtRect.Height()),
			                   m_strTextFormat, &boundingBox, &nchar, &m_nLineInRect);

		graphics.MeasureString(m_strText, -1, m_pFont, RectF((Gdiplus::REAL)0,    (Gdiplus::REAL)0,
			                                                 (Gdiplus::REAL)m_rtRect.Width(), (Gdiplus::REAL)m_rtRect.Height() + 100000),
			                   m_strTextFormat, &boundingBox, &nchar, &m_nLineALL);
	}
}

void CCustomEdit::SetString(const CString &str)
{
	if(m_strText != str){ m_strText = str;  this->InvalidateRect(NULL); }

	GetWindowTextW(m_strText);
	if(m_strText)
	{
		CreateFont();		
		Graphics graphics(m_hEditDC);

		RectF boundingBox; int nchar;
		graphics.MeasureString(m_strText, -1, m_pFont, RectF((Gdiplus::REAL)0,    (Gdiplus::REAL)0,
			                                                 (Gdiplus::REAL)m_rtRect.Width(), (Gdiplus::REAL)m_rtRect.Height()),
			                   m_strTextFormat, &boundingBox, &nchar, &m_nLineInRect);

		graphics.MeasureString(m_strText, -1, m_pFont, RectF((Gdiplus::REAL)0,    (Gdiplus::REAL)0, 
			                                                 (Gdiplus::REAL)m_rtRect.Width(), (Gdiplus::REAL)m_rtRect.Height() + 100000),
			                   m_strTextFormat, &boundingBox, &nchar, &m_nLineALL);
	}
}

void CCustomEdit::CreateFont()
{
	//----------------------new FontFamily
	if(m_pFontFamily == NULL)
		m_pFontFamily = new FontFamily(L"Verdana");
	if(FontFamilyNotFound == m_pFontFamily->GetLastStatus())
	{
		if (this->m_hWnd)
		{
			CFont *pCurFont = this->GetFont();  LOGFONT LgFong;  pCurFont->GetLogFont(&LgFong);
			if(m_pFontFamily){ delete m_pFontFamily;  m_pFontFamily = NULL;  m_pFontFamily = new FontFamily(LgFong.lfFaceName); }
		}
	}
	
	//----------------------new Font
	if(m_pFont == NULL)
		m_pFont = new Gdiplus::Font(m_pFontFamily,(Gdiplus::REAL)m_nFontSize, m_nFontStyle, m_enFontUnit);

	//----------------------new StringFormat
	if(m_strTextFormat == NULL)
	{
		m_strTextFormat = new StringFormat;
		m_strTextFormat->SetAlignment(StringAlignmentNear);
		m_strTextFormat->SetLineAlignment(StringAlignmentNear);
		m_strTextFormat->SetTrimming(StringTrimmingWord);
	}

	//----------------------new FontBrush
	if (m_pFontBrush == NULL)
		m_pFontBrush = new SolidBrush(Color(247, 247, 247, 247));
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
//UI Drawing
/*********************************************************************************************************************/
/*********************************************************************************************************************/
void CCustomEdit::DrawUI()
{
	BitBlt(m_hEditDC, 0, 0, m_rtRect.Width(), m_rtRect.Height(), m_hBgDC, m_rtRect.left, m_rtRect.top, SRCCOPY);
	Graphics graphics(m_hEditDC);

	GetWindowTextW(m_strText);
	if(!m_strText.IsEmpty())
	{
		CreateFont();
		float font_height= (float)m_pFont->GetHeight(&graphics);
		float top = -((float)m_nMovedLine * font_height);

		int n = graphics.DrawString(m_strText.GetBuffer(), -1, m_pFont, 
			                RectF((Gdiplus::REAL)0,                (Gdiplus::REAL)top,
			                      (Gdiplus::REAL)m_rtRect.Width(), (Gdiplus::REAL)m_rtRect.Height() - (Gdiplus::REAL)top),
			                m_strTextFormat, m_pFontBrush);
	}

	BitBlt(m_hDrawDC, m_rtRect.left, m_rtRect.top, m_rtRect.Width(), m_rtRect.Height(), m_hEditDC, 0, 0, SRCCOPY);
	CUtility::UpdateWindow(m_hPParentWnd, m_hDrawDC, m_rtPPRect);
}

void CCustomEdit::DrawItem(LPDRAWITEMSTRUCT di)
{
	DrawUI();
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
//UI Message
/*********************************************************************************************************************/
/*********************************************************************************************************************/
BEGIN_MESSAGE_MAP(CCustomEdit, CEdit)
	ON_WM_DRAWITEM()
//	ON_WM_ERASEBKGND()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void CCustomEdit::PreSubclassWindow()
{
	// TODO: Add your specialized code here and/or call the base class
	ModifyStyle(0, BS_OWNERDRAW);
	wchar_t strText[256];
	GetWindowText(strText, 256);
	SetString(strText);

	CEdit::PreSubclassWindow();
}


BOOL CCustomEdit::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}
